/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.thienloc.omap.controller;

import com.thienloc.omap.entity.GiaiThuong;
import com.thienloc.omap.entity.Kqxs;
import com.thienloc.omap.entity.LotterySchedule;
import com.thienloc.omap.entity.TinhThanh;
import com.thienloc.omap.lotteryanalyze.Pattern;
import com.thienloc.omap.lotteryanalyze.WebAnalyzer;
import com.thienloc.omap.session.GiaiThuongFacade;
import com.thienloc.omap.session.KqxsFacade;
import com.thienloc.omap.session.LotteryScheduleFacade;
import com.thienloc.omap.session.TinhThanhFacade;
import com.thienloc.omap.util.Constant;
import com.thienloc.omap.util.JsfUtil;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

/**
 *
 * @author GiangLT
 */
@ManagedBean(name = "lotteryBean")
@ViewScoped
public class LotteryBean extends AbstractCrudBean {

    @EJB
    private KqxsFacade facade;
    @EJB
    private GiaiThuongFacade giaiThuongFacade;
    @EJB
    private TinhThanhFacade tinhThanhFacade;
    @EJB
    private LotteryScheduleFacade lotteryScheduleFacade;
    private Kqxs selected;
    private List<Kqxs> list;
    private Map<String, String> provinces;
    private Map<String, String> allAreas;
    private Date startDate;
    private Date endDate;
    private Date openDate;
    private Date parseTime;
    private String selectedProvince = "all";
    private String selectedWebsite;
    private String rawLotteryText;

    /**
     * Creates a new instance of LotteryBean
     */
    public LotteryBean() {
    }

    @PostConstruct
    @Override
    public void init() {
        logger.trace("[{}] Initializing Bean: {}", getUsername(), this.getClass().getSimpleName());
        resetToCreateForm();
        try {
            logger.debug("[{}] Finding all areas using {}", getUsername(), facade.getClass().getSimpleName());
            List<String> areas = facade.findAvaiableAreas();
            allAreas = new TreeMap<String, String>();
            for (String area : areas) {
                if (area != null && !area.isEmpty()) {
                    allAreas.put(area, area);
                }
            }
            selected.setNgayQuay(new Date());
            selected.setTinhQuay("MB");
            onChangeDate();

            Calendar yesterday = Calendar.getInstance();
            yesterday.add(Calendar.DATE, -1);
            startDate = yesterday.getTime();
            endDate = yesterday.getTime();
            findLotteryResults();
        } catch (Exception ex) {
            logger.error("[{}]: ", getUsername(), ex);
        }
        logger.trace("[{}] Done initialize Bean: {}", getUsername(), this.getClass().getSimpleName());
    }

    public void onChangeDate() {
        logger.trace("[{}] Finding lottery schedule by dayOfWeek", getUsername());
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(selected.getNgayQuay());

        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        List<LotterySchedule> lotterySchedules = lotteryScheduleFacade.findByDayOfWeek(dayOfWeek);
        provinces = new TreeMap<String, String>();
        try {
            for (LotterySchedule lotterySchedule : lotterySchedules) {
                provinces.put(lotterySchedule.getProvinceId().getTenTinh() + " - " + lotterySchedule.getProvinceId().getMaTinh(), lotterySchedule.getProvinceId().getTenTinh());
            }
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }
        logger.trace("[{}] Done finding lottery schedule by dayOfWeek", getUsername());
    }

    public void fixKqxs() {
        logger.trace("[{}] Fixing Kqxs", getUsername());
        try {
            facade.fixKqxs();
            JsfUtil.addSuccessMessage("Thành công!", "Đã sửa xong các KQXS bị sai");
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }
        logger.trace("[{}] Done fixing Kqxs", getUsername());
    }

    public void findLotteryResults() {
        logger.trace("[{}] Finding loterry results", getUsername());
        try {
            startDate.setHours(0);
            startDate.setMinutes(0);
            startDate.setSeconds(0);

            endDate.setHours(23);
            endDate.setMinutes(59);
            endDate.setSeconds(59);
            validateForm();
            if (selectedProvince.equals("all")) {
                list = facade.findBetweenDate(startDate, endDate);
            } else {
                list = facade.findByArea(selectedProvince, startDate, endDate);
            }

            if (list == null || list.isEmpty()) {
                JsfUtil.addMessage(FacesMessage.SEVERITY_WARN, "Không tìm thấy dữ liệu", "Hãy thử lại ở tỉnh khác hoặc khoảng thời gian khác");
            } else {
                Comparator<GiaiThuong> comparator = new Comparator<GiaiThuong>() {

                    @Override
                    public int compare(GiaiThuong o1, GiaiThuong o2) {
                        return o2.getId().compareTo(o1.getId());
                    }
                };
                for (Kqxs kqxs : list) {
                    Collections.sort(kqxs.getGiaiThuongList(), comparator);
                }
            }
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }
        logger.trace("[{}] Done finding loterry results", getUsername());
    }

    public void delete(Kqxs kqxs) {
        logger.trace("[{}] Deleting a loterry result {}", getUsername(), kqxs.getId());
        try {
            facade.deleteById(kqxs.getId());
            list.remove(kqxs);
            JsfUtil.addSuccessMessage("Thành công!", "Xóa thành công 1 bản ghi");
        } catch (Exception e) {
            logAndNotifyError(e);
        }
        logger.trace("[{}] Done deleting a loterry result {}", getUsername(), kqxs.getId());
    }

    public void saveResult() {
        logger.trace("[{}] Saving loterry result {}", getUsername());
        try {
            String tinh = selected.getTinhQuay();
            Date ngayQuay = selected.getNgayQuay();
            DateFormat df = new SimpleDateFormat("yyyyMMdd");
            selected.setNgayQuayStr(df.format(ngayQuay));
            parseRawText();

            List<GiaiThuong> giaiThuongs = selected.getGiaiThuongList();
            selected.setGiaiThuongList(null);


            Kqxs kqxs = facade.find(tinh, df.format(ngayQuay));
            if (kqxs == null) {
                facade.create(selected);
                kqxs = facade.find(tinh, df.format(ngayQuay));
                for (GiaiThuong giaiThuong : giaiThuongs) {
                    giaiThuong.setIdKqxs(kqxs);
                    giaiThuongFacade.create(giaiThuong);
                }
            } else {
                giaiThuongFacade.deleteByKqxsId(kqxs.getId());
                for (GiaiThuong giaiThuong : giaiThuongs) {
                    giaiThuong.setIdKqxs(kqxs);
                    giaiThuongFacade.create(giaiThuong);
                }
            }

            JsfUtil.addSuccessMessage("Thành công!", "Đã cập nhât thành công KQXS");
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }
        logger.trace("[{}] Done saving loterry result {}", getUsername());
    }

    public void parseRawText() {
        logger.trace("[{}] Parsing raw lottery result text{}", getUsername());
        try {
            String tinh = selected.getTinhQuay();
            Date ngayQuay = selected.getNgayQuay();

            TinhThanh tinhThanh = tinhThanhFacade.findByTenTinh(selected.getTinhQuay());
            Pattern[] patterns = Constant.kqxsPatternMap.get(tinhThanh.getVungMien());
            WebAnalyzer analyzer = new WebAnalyzer(patterns);

            selected = analyzer.analyzeKqxs(rawLotteryText);
            selected.setTinhQuay(tinh);
            selected.setNgayQuay(ngayQuay);
            selected.setGioCapNhatCuoi(new Date());
            selected.setGioKhoiTao(new Date());
            selected.setPublicBool((short) 1);
            selected.setPhamVi(tinh);
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }
        logger.trace("[{}] Done parsing raw lottery result text{}", getUsername());
    }

    private GiaiThuong createGiaiThuong(String[] cacBoSo, String tenGiai, Kqxs id) {
        GiaiThuong giaiThuong = new GiaiThuong();
        giaiThuong.setIdKqxs(id);
        giaiThuong.setTenGiai(tenGiai);
        int length = cacBoSo.length;
        if (length > 0) {
            giaiThuong.setBoSo1(cacBoSo[0]);
        }
        if (length > 1) {
            giaiThuong.setBoSo2(cacBoSo[1]);
        }
        if (length > 2) {
            giaiThuong.setBoSo3(cacBoSo[2]);
        }
        if (length > 3) {
            giaiThuong.setBoSo4(cacBoSo[3]);
        }
        if (length > 4) {
            giaiThuong.setBoSo5(cacBoSo[4]);
        }
        if (length > 5) {
            giaiThuong.setBoSo6(cacBoSo[5]);
        }
        if (length > 6) {
            giaiThuong.setBoSo7(cacBoSo[6]);
        }
        if (length > 7) {
            giaiThuong.setBoSo8(cacBoSo[7]);
        }

        return giaiThuong;
    }

    //<editor-fold defaultstate="collapsed" desc="Getters & Setters">
    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public String getSelectedProvince() {
        return selectedProvince;
    }

    public void setSelectedProvince(String selectedProvince) {
        this.selectedProvince = selectedProvince;
    }

    public Date getOpenDate() {
        return openDate;
    }

    public void setOpenDate(Date openDate) {
        this.openDate = openDate;
    }

    public String getSelectedWebsite() {
        return selectedWebsite;
    }

    public void setSelectedWebsite(String selectedWebsite) {
        this.selectedWebsite = selectedWebsite;
    }

    public Date getParseTime() {
        return parseTime;
    }

    public void setParseTime(Date parseTime) {
        this.parseTime = parseTime;
    }

    public List<Kqxs> getList() {
        return list;
    }

    public void setList(List<Kqxs> list) {
        this.list = list;
    }

    public Kqxs getSelected() {
        return selected;
    }

    public void setSelected(Kqxs selected) {
        this.selected = selected;
    }

    public String getRawLotteryText() {
        return rawLotteryText;
    }

    public void setRawLotteryText(String rawLotteryText) {
        this.rawLotteryText = rawLotteryText;
    }

    public Map<String, String> getProvinces() {
        return provinces;
    }
    //</editor-fold>

    @Override
    protected Logger getLogger() {
        return LoggerFactory.getLogger(LotteryBean.class);
    }

    @Override
    protected void resetToCreateFormAction() throws Exception {
        list = new ArrayList<Kqxs>(0);
        selected = new Kqxs();
        edit = false;
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        startDate = cal.getTime();
        cal.add(Calendar.DAY_OF_MONTH, 1);
        endDate = cal.getTime();
    }

    @Override
    protected void findSelected(int id) throws Exception {
        selected = facade.find(id);
    }

    @Override
    protected void createSelected() throws Exception {
        facade.create(selected);
        resetToCreateForm();
        JsfUtil.addSuccessMessage("Thành công!", "Đã thêm mới thành công một bản ghi");
    }

    @Override
    protected void editSelected() throws Exception {
        facade.edit(selected);
        resetToCreateForm();
        JsfUtil.addSuccessMessage("Thành công!", "Đã cập nhật thành công một bản ghi");
    }

    @Override
    protected void removeSelected() throws Exception {
        Integer id = Integer.parseInt(JsfUtil.getRequestParameter("id"));
        selected = facade.find(id);
        facade.remove(selected);
        resetToCreateForm();
        JsfUtil.addSuccessMessage("Thành công!", "Đã xóa thành công một bản ghi");
    }

    @Override
    protected void prepareViewAction() throws Exception {
    }

    @Override
    protected void prepareEditAction() throws Exception {
        edit = true;
        Integer id = Integer.parseInt(JsfUtil.getRequestParameter("id"));
        selected = facade.find(id);
    }

    @Override
    protected void validateForm() throws Exception {
        if (endDate.before(startDate)) {
            throw new Exception("Ngày bắt đầu phải trước ngày kết thúc");
        }
    }

    public Map<String, String> getAllAreas() {
        return allAreas;
    }

    public void setAllAreas(Map<String, String> allAreas) {
        this.allAreas = allAreas;
    }
}
